package providers

import (
	"fmt"
	"time"

	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

const _cMysqlHeartbeat = 60

var Mysqls map[string]*gorm.DB

func init() {
	mysqlMap := Config.GetStringMap("mysqls")

	Mysqls = make(map[string]*gorm.DB)

	for mysqlName, mysqlConf := range mysqlMap {
		if !mysqlConf.(map[string]interface{})["is-start"].(bool) {
			continue
		}

		var err error
		Mysqls[mysqlName], err = _getMysqlClient(mysqlName)
		if err != nil {
			panic(mysqlName + "数据库初始化打开失败:" + err.Error())
		}

		Mysqls[mysqlName].DB().Ping()

		// 心跳
		go _mysqlHeartbeatRun(mysqlName)
	}

}

/**
 * 获取 mysql 客户端
 */
func _getMysqlClient(mysqlName string) (*gorm.DB, error) {
	config := Config.GetStringMapString("mysqls." + mysqlName)
	protocol := fmt.Sprintf(
		"%s:%s@tcp(%s)/%s?charset=utf8&parseTime=True&loc=Local",
		config["user"],
		config["password"],
		config["host"],
		config["dbname"],
	)

	return gorm.Open("mysql", protocol)

}

/**
 * 重置 mysql 客户端
 */
func _resetMysqlClient(mysqlName string) {
	if Mysqls[mysqlName] != nil {
		Mysqls[mysqlName].Close()
	}

	var err error
	Mysqls[mysqlName], err = _getMysqlClient(mysqlName)
	if err != nil {
		Logger.Errorf(mysqlName+"数据库初始化打开失败!%s", err.Error())
	}
}

/**
 * mysql 心跳
 */
func _mysqlHeartbeatRun(mysqlName string) {
	timer := time.NewTicker(_cMysqlHeartbeat * time.Second)
	for {
		select {
		case <-timer.C: // 每一分钟 ping 一次
			if err := Mysqls[mysqlName].DB().Ping(); err != nil {
				Logger.Errorf(mysqlName+"数据库 无法 ping 通!%s", err.Error())
				_resetMysqlClient(mysqlName)
			}
		}
	}
}
